package testApplets;

import java.util.ArrayList;
import java.util.Vector;

import meshToSolid.Selector;

import peasy.PeasyCam;
import processing.core.PApplet;
import simpleGeom.AbstractFace;
import simpleGeom.BasicMesh;
import simpleGeom.Bounds3D;
import simpleGeom.Face3D;
import simpleGeom.HasPos3D;
import simpleGeom.Mesh;
import simpleGeom.MeshFace;
import simpleGeom.Node;
import simpleGeom.SimpleTriangle;
import simpleGeom.TriangleMath;

public class BooleanMeshApplet extends PApplet {
	String folderPath = "/Users/caad/Desktop/Archive/excerpt/";
	// String inputPath=folderPath+"grottoVolume.obj";
	String inputPath = folderPath
			+ "testPiece6.objH0.4_0.13_0.1_0.24inside0.15res005.objSel.obj";

	String outputPath = inputPath + "Sel.obj";
	Bounds3D b3d;
	Face3D maxX;
	BasicMesh mesh;
	BasicMesh tube;
	PeasyCam cam;

	public void setup() {
		size(1600, 900, P3D);
		mesh = new BasicMesh();
		 mesh.load(inputPath);
		float d = 0.07f;
		float px=0.3f;
		float py=0.25f;
		BasicMesh tube1 = getTube(px, py, -1, px + d, py + d, 1);
		 px=0.3f;
		 py=-0.25f;
		 BasicMesh tube2 = getTube(px, py, -1, px + d, py + d, 1);
		 tube=new BasicMesh();
		 tube.nodes.addAll(tube1.nodes);
		 tube.faces.addAll(tube1.faces);
		 tube.nodes.addAll(tube2.nodes);
		 tube.faces.addAll(tube2.faces);
		cam = new PeasyCam(this, 400);
		ArrayList<AbstractFace>tris=intersect(mesh,tube.faces);
		mesh.faces=tris;
		mesh.saveObj(inputPath+"holes.obj");
	}

	public BasicMesh getTube(float x1, float y1, float z1, float x2, float y2,
			float z2) {
		BasicMesh mesh = new BasicMesh();

		Vector<Node> nodesLeft = new Vector<Node>();
		nodesLeft.add(new Node(x1, y1, z1));
		nodesLeft.add(new Node(x2, y1, z1));
		nodesLeft.add(new Node(x2, y2, z1));
		nodesLeft.add(new Node(x1, y2, z1));

		Vector<Node> nodesRight = new Vector<Node>();
		nodesRight.add(new Node(x1, y1, z2));
		nodesRight.add(new Node(x2, y1, z2));
		nodesRight.add(new Node(x2, y2, z2));
		nodesRight.add(new Node(x1, y2, z2));

		for (int i = 0; i < nodesLeft.size(); i++) {
			Node n1 = nodesLeft.get(i);
			Node n2 = nodesLeft.get((i + 1) % 4);
			Node b1 = nodesRight.get(i);
			Node b2 = nodesRight.get((i + 1) % 4);
			SimpleTriangle sT1 = new SimpleTriangle(n1, n2, b1);
			SimpleTriangle sT2 = new SimpleTriangle(b2, b1, n2);
			mesh.faces.add(sT1);
			mesh.faces.add(sT2);
		}

		mesh.nodes.addAll(nodesLeft);
		mesh.nodes.addAll(nodesRight);
	
		return mesh;
	}
	//b3d.getOffset();
	//Vector<Face3D>selectedFaces=selector.selectFaces(selector.faces, b3d, maxX, true);
	
	public void draw() {
		background(0);
		
		lights();

		scale(100);
		fill(255);
		noStroke();
		
		tube.display3D(g);
		//mesh.display3D(g);
		for (int i=0;i<mesh.faces.size();i+=20){
			AbstractFace tri=mesh.faces.get(i);
			tri.display3D(g);
		}
	}

	public ArrayList<AbstractFace> intersect(BasicMesh mesh,
			ArrayList<AbstractFace> triangles) {
		ArrayList<AbstractFace> tris = new ArrayList<AbstractFace>(triangles);
		for (int i = 0; i < tris.size(); i++) {
			SimpleTriangle tri = (SimpleTriangle) tris.get(i);
			tri.setId(0);
		}
		for (int j = 0; j < mesh.faces.size(); j++) {
			if (j%1000000==0)println("j"+j+"/"+ mesh.faces.size());
			SimpleTriangle face = (SimpleTriangle)mesh.faces.get(j);
			for (int i = 0; i < tris.size(); i++) {
				SimpleTriangle tri = (SimpleTriangle) tris.get(i);
				if (tri.getId() == 0) {
					TriangleMath math = new TriangleMath();
					Vector<SimpleTriangle> cSplits = math.intersectTriPlane(
							tri.getNode(0), tri.getNode(1), tri.getNode(2),
							face.getNode(0), face.getNode(1), face.getNode(2));
					tris.addAll(cSplits);
					if (cSplits.size() > 0) {
						tri.setId(10000);
					}
				}
			}
		}
		ArrayList<AbstractFace> finaltris = new ArrayList<AbstractFace>();
		for (int i = 0; i < tris.size(); i++) {
			SimpleTriangle tri = (SimpleTriangle) tris.get(i);
			HasPos3D center=tri.getGravityCenter();
			if (!BasicMesh.contains(center.getX(), center.getY(),center.getZ(),0,1,0, mesh.faces)){
			if (tri.getId() == 0){
				finaltris.add(tri);
			}
			}
		}
		println("finaltris: "+finaltris.size());
		return finaltris;
	}
}
